Como conquistar o crush (tutorial)

Todo mundo em algum momento provavelmente já se questionou : Será que eu tenho chance com fulano/fulana? O que eu tenho que fazer pra conquistar essa pessoa? O que será que faz com que ela/ele goste de outra pessoa?

Você provavelmente pensou na resposta óbvia, beleza. Mas… será que é só isso mesmo? NÃO! Existem outros fatores envolvidos e beleza não é a resposta mágica para um vida amorosa de sucesso. Iremos aqui analisar dados sobre vários encontros no modelo speed-dating (pode ir no google rs) entre pessoas desconhecidas. Ao final desses encontros todas as pessoas envolvidas preencheram um formulário detalhando o que acharam da outra pessoa com quem se encontraram. Nós vamos utilizar esses dados para verificar quais são as características cruciais para que uma pessoa goste de outra.

Vamos direto ao ponto, os dados que vamos analisar de cada encontro consistem basicamente em:
like: O quanto a pessoa 1 gostou da pessoa 2.
attr: O quanto a pessoa 1 achou a pessoa 2 atraente.
fun: Quão divertida(o) a pessoa 1 achou a pessoa 2.
intel: Quão inteligente a pessoa 1 achou a pessoa 2.
shar: O quanto a pessoa 1 achou que compartilha interesses com a pessoa 2.

Observemos primeiro a relação entre as variáveis citadas do ponto de vista dos homens, dando foco principalmente nas relações da variável like com as outras variáveis:

  dados = read_csv('dados.csv') %>% filter(complete.cases(.))
  dados_mulheres = dados %>% filter(gender == 0)
  dados_homens = dados %>% filter(gender == 1)

  dados_homens %>% 
    select(like, attr, fun, intel, shar) %>%
    ggpairs(size = .5, 
            lower = list(continuous = wrap("points", alpha = 0.3)))

Pela correlação das variáveis apresentadas com a variável like, podemos achar que para os homens que fizeram o experimento na hora de decidir se gosta de alguém ou não o bom-humor é o fator MAIS importante. Contudo beleza, e compartilhamento de interesses ainda parecem ser quesitos importantes. Aparantemente inteligência não parece ser um fator importante para os homens :p (Não me surpreendi com esse resultado hahaha).

  dados_mulheres %>% 
    select(like, attr, fun, intel, shar) %>%
    ggpairs(size = .5, 
            lower = list(continuous = wrap("points", size = .5, alpha = 0.3)))

Já para as mulheres obtivemos um resultado parecido, contudo, o fator beleza parece ser o mais importante. Seguido de perto por bom-humor e compartilhamento de interesses. As mulheres parecem também se importar mais com o quesito inteligência, porém não tanto quanto eu esperava rs.

Com isso, duas perguntas óbvias aparecem na nossa mente. A primeira delas é:

Pergunta 1: Quais os fatores mais importantes para uma mulher gostar de outra pessoa?

Para responder essas perguntas, vamos tentar gerar uma regressão para explicar a variável like utilizando estes outros quatro fatores que estamos observando:

mulheres.model = lm(like ~ attr + fun + shar + intel, data = dados_mulheres)
summary(mulheres.model)

Call:
lm(formula = like ~ attr + fun + shar + intel, data = dados_mulheres)

Residuals:
    Min      1Q  Median      3Q     Max 
-4.0451 -0.5827  0.0844  0.6572  3.5584 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.18162    0.18057  -1.006    0.315    
attr         0.34236    0.02431  14.082  < 2e-16 ***
fun          0.18774    0.02618   7.172 1.64e-12 ***
shar         0.27356    0.02090  13.087  < 2e-16 ***
intel        0.20108    0.02795   7.195 1.39e-12 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.044 on 830 degrees of freedom
Multiple R-squared:  0.6772,    Adjusted R-squared:  0.6757 
F-statistic: 435.3 on 4 and 830 DF,  p-value: < 2.2e-16

Validando o modelo

Vamos verificar a validade do modelo encontrado confrontando-o com alguns problemas comuns.

Colinearidade entre variáveis explicativas

Já vimos anteriormente que nossas variáveis explicativas possuem um certo nível de correlação, contudo, será que isso é um problema para o modelo? Vamos calcular quanto cada fator contribui para a variância do modelo

vif(mulheres.model)
    attr      fun     shar    intel 
1.582624 2.054086 1.524048 1.459195 

Como a recomendação é que VIF < 5, não teremos problemas devido a colineriadade dos fatores explicativos.

Outliers e High Leverage points

Vamos utilizar um QQ Plot (quantil quantil plot) para observar os resíduos “studentizados” do nosso modelo e verificar se temos algum ponto suspeito.

qqPlot(mulheres.model, main="QQ Plot")

Temos alguns pontos com resíduos suspeitos, o ideal seria investigar quais são esses pontos e se eles realmente fazem sentido (help wanted). Contudo, os resíduos parecem estar distribuídos de maneira quase normal portanto com isso não teremos problemas.

Interpretação do modelo e resposta para a pergunta 1

O valor obtido para o R-quadrado do nosso modelo foi 0.6757 ou seja, nosso modelo explica 67.57% da variância dos dados. Valor razoável, dada a grande dispersão presente nos dados.

Todas as variáveis explicativas utilizadas foram significativas e, para as mulheres, as mais significativas foram (nessa ordem):

1 - Beleza
2 - Compartilhamento de interesses
3 - Inteligência
4 - Quão engraçada é a outra pessoa

Por fim, vamos visualizar o modelo obtido. Como temos 4 variáveis explicativas seria necessário um espaço 5-dimensional para visualiza-lo. Devido a isso vamos visualizar da seguinte maneira:

Eixo x - variável attr.
Eixo y - predição feita pelo modelo para a variável like.
Cor dos pontos - variável fun.
Tamanho dos pontos - variável shar.
Facetas do gráfico - variável intel.

para_plotar_modelo = dados_mulheres %>% 
  data_grid(attr = seq_range(attr, 10), 
            fun = seq_range(fun, 4), 
            intel = seq_range(intel, 3),
            shar = seq_range(shar, 3)) %>% add_predictions(mulheres.model)

ggplotly(ggplot(para_plotar_modelo, aes(x = attr, y = pred)) + 
  geom_point(aes(colour = fun, size = shar)) + facet_grid(. ~intel))

Pergunta 2: Quais os fatores mais importantes para um homem gostar de outra pessoa?

Da mesma maneira que fizemos para as mulheres vamos tentar gerar uma regressão para explicar a variável like.

homens.model = lm(like ~ attr + fun + shar + intel, data = dados_homens)
summary(homens.model)

Call:
lm(formula = like ~ attr + fun + shar + intel, data = dados_homens)

Residuals:
    Min      1Q  Median      3Q     Max 
-4.4723 -0.4983  0.0868  0.5807  6.5524 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  0.44610    0.19215   2.322 0.020509 *  
attr         0.36008    0.02545  14.149  < 2e-16 ***
fun          0.21475    0.02931   7.325 5.94e-13 ***
shar         0.23826    0.02231  10.677  < 2e-16 ***
intel        0.11079    0.02935   3.775 0.000172 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.082 on 782 degrees of freedom
Multiple R-squared:  0.6336,    Adjusted R-squared:  0.6317 
F-statistic:   338 on 4 and 782 DF,  p-value: < 2.2e-16

Validando o modelo

Colinearidade entre variáveis explicativas

Assim como para as mulheres, as nossas variáveis explicativas possuem um certo nível de correlação, contudo, será que isso implica em colinearidade? Vamos calcular quanto cada fator contribui para a variância do modelo

vif(homens.model)
    attr      fun     shar    intel 
1.494094 2.132659 1.595476 1.456691 

Como a recomendação é que VIF < 5, novamente não teremos problemas devido a colineriadade das nossas variáveis independentes.

Outliers e High Leverage points

Vamos utilizar um QQ Plot (quantil quantil plot) para observar os resíduos “studentizados” do nosso modelo e verificar se temos algum ponto suspeito.

qqPlot(homens.model, main="QQ Plot")

Temos alguns pontos com resíduos suspeitos na parte de baixo do gráfico e um ponto MUITO suspeito com 6 de resíduo studentizado. Este ponto provalvemente não representa o padrão geral dos dados e deve ser removido para não afetar muito o nosso modelo (help wanted!). Contudo, os resíduos parecem estar distribuídos de maneira quase normal portanto com isso não teremos problemas.

Interpretação do modelo e resposta para a pergunta 2

O valor obtido para o R-quadrado do nosso modelo foi 0.6317 ou seja, nosso modelo explica 63.17% da variância dos dados. Valor razoável, dada a grande dispersão presente nos dados.

Todas as variáveis explicativas utilizadas foram significativas e, para os homens, as mais significativas foram (nessa ordem):

1 - Beleza
2 - Compartilhamento de interesses
3 - Quão engraçada é a outra pessoa
4 - Inteligência

Por fim, vamos visualizar o modelo obtido. Como temos 4 variáveis explicativas seria necessário um espaço 5-dimensional para visualiza-lo. Devido a isso vamos visualizar da seguinte maneira:

Eixo x: variável attr.
Eixo y: predição feita pelo modelo para a variável like.
Cor dos pontos: variável fun.
Tamanho dos pontos: variável shar.
Facetas do gráfico: variável intel.

para_plotar_modelo = dados_homens %>% 
  data_grid(attr = seq_range(attr, 10), 
            fun = seq_range(fun, 4), 
            intel = seq_range(intel, 3),
            shar = seq_range(shar, 3)) %>% add_predictions(homens.model)

ggplotly(ggplot(para_plotar_modelo, aes(x = attr, y = pred)) + 
  geom_point(aes(colour = fun, size = shar)) + facet_grid(. ~intel))

Conclusao

Me parece que a hipótese que fizemos no começo desse relatório está correta! Apesar de para ambos os sexos o fator beleza ter sido o mais significativo na regressão… Contudo, vimos que beleza não é o único fator que as pessoas levam em conta na hora de gostar alguém.

Para as mulheres interesses em comum e inteligência também parecem ser fatores importantes. Já para os homens é importante também que a outra pessoa seja engraçada e que compartilhe interesses em comum.

Porém vale lembrar que estamos tratando de seres humanos! E nunca vamos conseguir definir uma fórmula fechada para algo tão complexo como um relacionamento entre duas pessoas… A minha é dica é: Seja você mesmo! Autenticidade não está nos dados, mas com certeza seria significativo se estivesse.

LS0tCnRpdGxlOiAibGFiNS1jcDEiCmRhdGU6ICIyMi8wOC8yMDE3IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojQ29tbyBjb25xdWlzdGFyIG8gY3J1c2ggKHR1dG9yaWFsKQpUb2RvIG11bmRvIGVtIGFsZ3VtIG1vbWVudG8gcHJvdmF2ZWxtZW50ZSBqw6Egc2UgcXVlc3Rpb25vdSA6IFNlcsOhIHF1ZSBldSB0ZW5obyBjaGFuY2UgY29tIGZ1bGFuby9mdWxhbmE/IE8gcXVlIGV1IHRlbmhvIHF1ZSBmYXplciBwcmEgY29ucXVpc3RhciBlc3NhIHBlc3NvYT8gTyBxdWUgc2Vyw6EgcXVlIGZheiBjb20gcXVlIGVsYS9lbGUgZ29zdGUgZGUgb3V0cmEgcGVzc29hPwoKVm9jw6ogcHJvdmF2ZWxtZW50ZSBwZW5zb3UgbmEgcmVzcG9zdGEgw7NidmlhLCA8Yj5iZWxlemE8L2I+LiBNYXMuLi4gc2Vyw6EgcXVlIMOpIHPDsyBpc3NvIG1lc21vPyA8Yj5Ow4NPITwvYj4gRXhpc3RlbSBvdXRyb3MgZmF0b3JlcyBlbnZvbHZpZG9zIGUgYmVsZXphIG7Do28gw6kgYSByZXNwb3N0YSBtw6FnaWNhIHBhcmEgdW0gdmlkYSBhbW9yb3NhIGRlIHN1Y2Vzc28uIElyZW1vcyBhcXVpIGFuYWxpc2FyIGRhZG9zIHNvYnJlIHbDoXJpb3MgZW5jb250cm9zIG5vIG1vZGVsbyBfc3BlZWQtZGF0aW5nXyAocG9kZSBpciBubyBnb29nbGUgcnMpIGVudHJlIHBlc3NvYXMgZGVzY29uaGVjaWRhcy4gQW8gZmluYWwgZGVzc2VzIGVuY29udHJvcyB0b2RhcyBhcyBwZXNzb2FzIGVudm9sdmlkYXMgcHJlZW5jaGVyYW0gdW0gZm9ybXVsw6FyaW8gZGV0YWxoYW5kbyBvIHF1ZSBhY2hhcmFtIGRhIG91dHJhIHBlc3NvYSBjb20gcXVlbSBzZSBlbmNvbnRyYXJhbS4gTsOzcyB2YW1vcyB1dGlsaXphciBlc3NlcyBkYWRvcyBwYXJhIHZlcmlmaWNhciBxdWFpcyBzw6NvIGFzIGNhcmFjdGVyw61zdGljYXMgY3J1Y2lhaXMgcGFyYSBxdWUgdW1hIHBlc3NvYSBnb3N0ZSBkZSBvdXRyYS4KClZhbW9zIGRpcmV0byBhbyBwb250bywgb3MgZGFkb3MgcXVlIHZhbW9zIGFuYWxpc2FyIGRlIGNhZGEgZW5jb250cm8gY29uc2lzdGVtIGJhc2ljYW1lbnRlIGVtOjxicj4KPGI+bGlrZTwvYj46IE8gcXVhbnRvIGEgcGVzc29hIDEgZ29zdG91IGRhIHBlc3NvYSAyLiA8YnI+CjxiPmF0dHI8L2I+OiBPIHF1YW50byBhIHBlc3NvYSAxIGFjaG91IGEgcGVzc29hIDIgYXRyYWVudGUuIDxicj4KPGI+ZnVuPC9iPjogUXXDo28gZGl2ZXJ0aWRhKG8pIGEgcGVzc29hIDEgYWNob3UgYSBwZXNzb2EgMi4gPGJyPgo8Yj5pbnRlbDwvYj46IFF1w6NvIGludGVsaWdlbnRlIGEgcGVzc29hIDEgYWNob3UgYSBwZXNzb2EgMi4gPGJyPgo8Yj5zaGFyPC9iPjogTyBxdWFudG8gYSBwZXNzb2EgMSBhY2hvdSBxdWUgY29tcGFydGlsaGEgaW50ZXJlc3NlcyBjb20gYSBwZXNzb2EgMi4gPGJyPgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9IAogIGtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSkKICBzdXBwcmVzc1dhcm5pbmdzKGxpYnJhcnkodGlkeXZlcnNlKSkKICBsaWJyYXJ5KHRpZHl2ZXJzZSkKICBsaWJyYXJ5KEdHYWxseSkKICBsaWJyYXJ5KGJyb29tKQogIGxpYnJhcnkoZ2dmb3J0aWZ5KQogIGxpYnJhcnkoZ2dwbG90MikKICBsaWJyYXJ5KG1vZGVscikKICBsaWJyYXJ5KGNhcikKICBsaWJyYXJ5KHBsb3RseSkKCmBgYAoKT2JzZXJ2ZW1vcyBwcmltZWlybyBhIHJlbGHDp8OjbyBlbnRyZSBhcyB2YXJpw6F2ZWlzIGNpdGFkYXMgZG8gcG9udG8gZGUgdmlzdGEgZG9zIGhvbWVucywgZGFuZG8gZm9jbyBwcmluY2lwYWxtZW50ZSBuYXMgcmVsYcOnw7VlcyBkYSB2YXJpw6F2ZWwgX2xpa2VfIGNvbSBhcyBvdXRyYXMgdmFyacOhdmVpczoKCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQogIGRhZG9zID0gcmVhZF9jc3YoJ2RhZG9zLmNzdicpICU+JSBmaWx0ZXIoY29tcGxldGUuY2FzZXMoLikpCiAgZGFkb3NfbXVsaGVyZXMgPSBkYWRvcyAlPiUgZmlsdGVyKGdlbmRlciA9PSAwKQogIGRhZG9zX2hvbWVucyA9IGRhZG9zICU+JSBmaWx0ZXIoZ2VuZGVyID09IDEpCgogIGRhZG9zX2hvbWVucyAlPiUgCiAgICBzZWxlY3QobGlrZSwgYXR0ciwgZnVuLCBpbnRlbCwgc2hhcikgJT4lCiAgICBnZ3BhaXJzKHNpemUgPSAuNSwgCiAgICAgICAgICAgIGxvd2VyID0gbGlzdChjb250aW51b3VzID0gd3JhcCgicG9pbnRzIiwgYWxwaGEgPSAwLjMpKSkKYGBgCgpQZWxhIGNvcnJlbGHDp8OjbyBkYXMgdmFyacOhdmVpcyBhcHJlc2VudGFkYXMgY29tIGEgdmFyacOhdmVsIGxpa2UsIHBvZGVtb3MgYWNoYXIgcXVlIHBhcmEgb3MgaG9tZW5zIHF1ZSBmaXplcmFtIG8gZXhwZXJpbWVudG8gbmEgaG9yYSBkZSBkZWNpZGlyIHNlIGdvc3RhIGRlIGFsZ3XDqW0gb3UgbsOjbyBvIGJvbS1odW1vciDDqSBvIGZhdG9yIDxiPk1BSVM8L2I+IGltcG9ydGFudGUuIENvbnR1ZG8gYmVsZXphLCBlIGNvbXBhcnRpbGhhbWVudG8gZGUgaW50ZXJlc3NlcyBhaW5kYSBwYXJlY2VtIHNlciBxdWVzaXRvcyBpbXBvcnRhbnRlcy4gQXBhcmFudGVtZW50ZSBpbnRlbGlnw6puY2lhIG7Do28gcGFyZWNlIHNlciB1bSBmYXRvciBpbXBvcnRhbnRlIHBhcmEgb3MgaG9tZW5zIDpwIChOw6NvIG1lIHN1cnByZWVuZGkgY29tIGVzc2UgcmVzdWx0YWRvIGhhaGFoYSkuCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KICBkYWRvc19tdWxoZXJlcyAlPiUgCiAgICBzZWxlY3QobGlrZSwgYXR0ciwgZnVuLCBpbnRlbCwgc2hhcikgJT4lCiAgICBnZ3BhaXJzKHNpemUgPSAuNSwgCiAgICAgICAgICAgIGxvd2VyID0gbGlzdChjb250aW51b3VzID0gd3JhcCgicG9pbnRzIiwgc2l6ZSA9IC41LCBhbHBoYSA9IDAuMykpKQpgYGAKCkrDoSBwYXJhIGFzIG11bGhlcmVzIG9idGl2ZW1vcyB1bSByZXN1bHRhZG8gcGFyZWNpZG8sIGNvbnR1ZG8sIG8gZmF0b3IgYmVsZXphIHBhcmVjZSBzZXIgbyBtYWlzIGltcG9ydGFudGUuIFNlZ3VpZG8gZGUgcGVydG8gcG9yIGJvbS1odW1vciBlIGNvbXBhcnRpbGhhbWVudG8gZGUgaW50ZXJlc3Nlcy4gQXMgbXVsaGVyZXMgcGFyZWNlbSB0YW1iw6ltIHNlIGltcG9ydGFyIG1haXMgY29tIG8gcXVlc2l0byBpbnRlbGlnw6puY2lhLCBwb3LDqW0gbsOjbyB0YW50byBxdWFudG8gZXUgZXNwZXJhdmEgcnMuCgpDb20gaXNzbywgZHVhcyBwZXJndW50YXMgw7NidmlhcyBhcGFyZWNlbSBuYSBub3NzYSBtZW50ZS4gQSBwcmltZWlyYSBkZWxhcyDDqToKCjxoMj5QZXJndW50YSAxOiBRdWFpcyBvcyBmYXRvcmVzIG1haXMgaW1wb3J0YW50ZXMgcGFyYSB1bWEgbXVsaGVyIGdvc3RhciBkZSBvdXRyYSBwZXNzb2E/PC9oMj4KClBhcmEgcmVzcG9uZGVyIGVzc2FzIHBlcmd1bnRhcywgdmFtb3MgdGVudGFyIGdlcmFyIHVtYSByZWdyZXNzw6NvIHBhcmEgZXhwbGljYXIgYSB2YXJpw6F2ZWwgbGlrZSB1dGlsaXphbmRvIGVzdGVzIG91dHJvcyBxdWF0cm8gZmF0b3JlcyBxdWUgZXN0YW1vcyBvYnNlcnZhbmRvOgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgptdWxoZXJlcy5tb2RlbCA9IGxtKGxpa2UgfiBhdHRyICsgZnVuICsgc2hhciArIGludGVsLCBkYXRhID0gZGFkb3NfbXVsaGVyZXMpCnN1bW1hcnkobXVsaGVyZXMubW9kZWwpCgpgYGAKCjxoMz5WYWxpZGFuZG8gbyBtb2RlbG88L2gzPgoKVmFtb3MgdmVyaWZpY2FyIGEgdmFsaWRhZGUgZG8gbW9kZWxvIGVuY29udHJhZG8gY29uZnJvbnRhbmRvLW8gY29tIGFsZ3VucyBwcm9ibGVtYXMgY29tdW5zLgoKPGgzPkNvbGluZWFyaWRhZGUgZW50cmUgdmFyacOhdmVpcyBleHBsaWNhdGl2YXM8L2gzPgoKSsOhIHZpbW9zIGFudGVyaW9ybWVudGUgcXVlIG5vc3NhcyB2YXJpw6F2ZWlzIGV4cGxpY2F0aXZhcyBwb3NzdWVtIHVtIGNlcnRvIG7DrXZlbCBkZSBjb3JyZWxhw6fDo28sIGNvbnR1ZG8sIHNlcsOhIHF1ZSBpc3NvIMOpIHVtIHByb2JsZW1hIHBhcmEgbyBtb2RlbG8/IFZhbW9zIGNhbGN1bGFyIHF1YW50byBjYWRhIGZhdG9yIGNvbnRyaWJ1aSBwYXJhIGEgdmFyacOibmNpYSBkbyBtb2RlbG8KCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp2aWYobXVsaGVyZXMubW9kZWwpCmBgYApDb21vIGEgcmVjb21lbmRhw6fDo28gw6kgcXVlIFZJRiA8IDUsIG7Do28gdGVyZW1vcyBwcm9ibGVtYXMgZGV2aWRvIGEgY29saW5lcmlhZGFkZSBkb3MgZmF0b3JlcyBleHBsaWNhdGl2b3MuCgo8aDM+T3V0bGllcnMgZSBIaWdoIExldmVyYWdlIHBvaW50czwvaDM+ClZhbW9zIHV0aWxpemFyIHVtIFFRIFBsb3QgKHF1YW50aWwgcXVhbnRpbCBwbG90KSBwYXJhIG9ic2VydmFyIG9zIHJlc8OtZHVvcyAic3R1ZGVudGl6YWRvcyIgZG8gbm9zc28gbW9kZWxvIGUgdmVyaWZpY2FyIHNlIHRlbW9zIGFsZ3VtIHBvbnRvIHN1c3BlaXRvLgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnFxUGxvdChtdWxoZXJlcy5tb2RlbCwgbWFpbj0iUVEgUGxvdCIpCgpgYGAKVGVtb3MgYWxndW5zIHBvbnRvcyBjb20gcmVzw61kdW9zIHN1c3BlaXRvcywgbyBpZGVhbCBzZXJpYSBpbnZlc3RpZ2FyIHF1YWlzIHPDo28gZXNzZXMgcG9udG9zIGUgc2UgZWxlcyByZWFsbWVudGUgZmF6ZW0gc2VudGlkbyAoaGVscCB3YW50ZWQpLiBDb250dWRvLCA8Yj5vcyByZXPDrWR1b3MgcGFyZWNlbSBlc3RhciBkaXN0cmlidcOtZG9zIGRlIG1hbmVpcmEgcXVhc2Ugbm9ybWFsPC9iPiBwb3J0YW50byBjb20gaXNzbyBuw6NvIHRlcmVtb3MgcHJvYmxlbWFzLgoKPGgzPkludGVycHJldGHDp8OjbyBkbyBtb2RlbG8gZSByZXNwb3N0YSBwYXJhIGEgcGVyZ3VudGEgMTwvaDM+Ck8gdmFsb3Igb2J0aWRvIHBhcmEgbyBSLXF1YWRyYWRvIGRvIG5vc3NvIG1vZGVsbyBmb2kgPGI+MC42NzU3PC9iPiBvdSBzZWphLCBub3NzbyBtb2RlbG8gZXhwbGljYSA8Yj42Ny41NyU8L2I+IGRhIHZhcmnDom5jaWEgZG9zIGRhZG9zLiBWYWxvciByYXpvw6F2ZWwsIGRhZGEgYSBncmFuZGUgZGlzcGVyc8OjbyBwcmVzZW50ZSBub3MgZGFkb3MuCgpUb2RhcyBhcyB2YXJpw6F2ZWlzIGV4cGxpY2F0aXZhcyB1dGlsaXphZGFzIGZvcmFtIHNpZ25pZmljYXRpdmFzIGUsIHBhcmEgYXMgbXVsaGVyZXMsIGFzIG1haXMgc2lnbmlmaWNhdGl2YXMgZm9yYW0gKG5lc3NhIG9yZGVtKToKCjEgLSBCZWxlemE8YnI+CjIgLSBDb21wYXJ0aWxoYW1lbnRvIGRlIGludGVyZXNzZXM8YnI+CjMgLSBJbnRlbGlnw6puY2lhPGJyPgo0IC0gUXXDo28gZW5ncmHDp2FkYSDDqSBhIG91dHJhIHBlc3NvYTxicj4KClBvciBmaW0sIHZhbW9zIHZpc3VhbGl6YXIgbyBtb2RlbG8gb2J0aWRvLiBDb21vIHRlbW9zIDQgdmFyacOhdmVpcyBleHBsaWNhdGl2YXMgc2VyaWEgbmVjZXNzw6FyaW8gdW0gZXNwYcOnbyA1LWRpbWVuc2lvbmFsIHBhcmEgdmlzdWFsaXphLWxvLiBEZXZpZG8gYSBpc3NvIHZhbW9zIHZpc3VhbGl6YXIgZGEgc2VndWludGUgbWFuZWlyYToKCkVpeG8geCAtIHZhcmnDoXZlbCBhdHRyLjxicj4KRWl4byB5IC0gcHJlZGnDp8OjbyBmZWl0YSBwZWxvIG1vZGVsbyBwYXJhIGEgdmFyacOhdmVsIGxpa2UuPGJyPgpDb3IgZG9zIHBvbnRvcyAtIHZhcmnDoXZlbCBmdW4uPGJyPgpUYW1hbmhvIGRvcyBwb250b3MgLSB2YXJpw6F2ZWwgc2hhci48YnI+CkZhY2V0YXMgZG8gZ3LDoWZpY28gLSB2YXJpw6F2ZWwgaW50ZWwuPGJyPgoKYGBge3IsIGZpZy53aWR0aD0xMiwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCnBhcmFfcGxvdGFyX21vZGVsbyA9IGRhZG9zX211bGhlcmVzICU+JSAKICBkYXRhX2dyaWQoYXR0ciA9IHNlcV9yYW5nZShhdHRyLCAxMCksIAogICAgICAgICAgICBmdW4gPSBzZXFfcmFuZ2UoZnVuLCA0KSwgCiAgICAgICAgICAgIGludGVsID0gc2VxX3JhbmdlKGludGVsLCAzKSwKICAgICAgICAgICAgc2hhciA9IHNlcV9yYW5nZShzaGFyLCAzKSkgJT4lIGFkZF9wcmVkaWN0aW9ucyhtdWxoZXJlcy5tb2RlbCkKCmdncGxvdGx5KGdncGxvdChwYXJhX3Bsb3Rhcl9tb2RlbG8sIGFlcyh4ID0gYXR0ciwgeSA9IHByZWQpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGZ1biwgc2l6ZSA9IHNoYXIpKSArIGZhY2V0X2dyaWQoLiB+aW50ZWwpKQoKYGBgCgo8aDI+UGVyZ3VudGEgMjogUXVhaXMgb3MgZmF0b3JlcyBtYWlzIGltcG9ydGFudGVzIHBhcmEgdW0gaG9tZW0gZ29zdGFyIGRlIG91dHJhIHBlc3NvYT88L2gyPgoKRGEgbWVzbWEgbWFuZWlyYSBxdWUgZml6ZW1vcyBwYXJhIGFzIG11bGhlcmVzIHZhbW9zIHRlbnRhciBnZXJhciB1bWEgcmVncmVzc8OjbyBwYXJhIGV4cGxpY2FyIGEgdmFyacOhdmVsIGxpa2UuCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCmhvbWVucy5tb2RlbCA9IGxtKGxpa2UgfiBhdHRyICsgZnVuICsgc2hhciArIGludGVsLCBkYXRhID0gZGFkb3NfaG9tZW5zKQpzdW1tYXJ5KGhvbWVucy5tb2RlbCkKCmBgYAoKPGgzPlZhbGlkYW5kbyBvIG1vZGVsbzwvaDM+Cgo8aDM+Q29saW5lYXJpZGFkZSBlbnRyZSB2YXJpw6F2ZWlzIGV4cGxpY2F0aXZhczwvaDM+CgpBc3NpbSBjb21vIHBhcmEgYXMgbXVsaGVyZXMsIGFzIG5vc3NhcyB2YXJpw6F2ZWlzIGV4cGxpY2F0aXZhcyBwb3NzdWVtIHVtIGNlcnRvIG7DrXZlbCBkZSBjb3JyZWxhw6fDo28sIGNvbnR1ZG8sIHNlcsOhIHF1ZSBpc3NvIGltcGxpY2EgZW0gY29saW5lYXJpZGFkZT8gVmFtb3MgY2FsY3VsYXIgcXVhbnRvIGNhZGEgZmF0b3IgY29udHJpYnVpIHBhcmEgYSB2YXJpw6JuY2lhIGRvIG1vZGVsbwoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnZpZihob21lbnMubW9kZWwpCmBgYApDb21vIGEgcmVjb21lbmRhw6fDo28gw6kgcXVlIFZJRiA8IDUsIG5vdmFtZW50ZSBuw6NvIHRlcmVtb3MgcHJvYmxlbWFzIGRldmlkbyBhIGNvbGluZXJpYWRhZGUgZGFzIG5vc3NhcyB2YXJpw6F2ZWlzIGluZGVwZW5kZW50ZXMuCgo8aDM+T3V0bGllcnMgZSBIaWdoIExldmVyYWdlIHBvaW50czwvaDM+ClZhbW9zIHV0aWxpemFyIHVtIFFRIFBsb3QgKHF1YW50aWwgcXVhbnRpbCBwbG90KSBwYXJhIG9ic2VydmFyIG9zIHJlc8OtZHVvcyAic3R1ZGVudGl6YWRvcyIgZG8gbm9zc28gbW9kZWxvIGUgdmVyaWZpY2FyIHNlIHRlbW9zIGFsZ3VtIHBvbnRvIHN1c3BlaXRvLgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnFxUGxvdChob21lbnMubW9kZWwsIG1haW49IlFRIFBsb3QiKQoKYGBgClRlbW9zIGFsZ3VucyBwb250b3MgY29tIHJlc8OtZHVvcyBzdXNwZWl0b3MgbmEgcGFydGUgZGUgYmFpeG8gZG8gZ3LDoWZpY28gZSB1bSBwb250byBNVUlUTyBzdXNwZWl0byBjb20gPGI+NjwvYj4gZGUgcmVzw61kdW8gc3R1ZGVudGl6YWRvLiBFc3RlIHBvbnRvIHByb3ZhbHZlbWVudGUgbsOjbyByZXByZXNlbnRhIG8gcGFkcsOjbyBnZXJhbCBkb3MgZGFkb3MgZSBkZXZlIHNlciByZW1vdmlkbyBwYXJhIG7Do28gYWZldGFyIG11aXRvIG8gbm9zc28gbW9kZWxvIChoZWxwIHdhbnRlZCEpLiBDb250dWRvLCA8Yj5vcyByZXPDrWR1b3MgcGFyZWNlbSBlc3RhciBkaXN0cmlidcOtZG9zIGRlIG1hbmVpcmEgcXVhc2Ugbm9ybWFsPC9iPiBwb3J0YW50byBjb20gaXNzbyBuw6NvIHRlcmVtb3MgcHJvYmxlbWFzLgoKPGgzPkludGVycHJldGHDp8OjbyBkbyBtb2RlbG8gZSByZXNwb3N0YSBwYXJhIGEgcGVyZ3VudGEgMjwvaDM+Ck8gdmFsb3Igb2J0aWRvIHBhcmEgbyBSLXF1YWRyYWRvIGRvIG5vc3NvIG1vZGVsbyBmb2kgPGI+MC42MzE3PC9iPiBvdSBzZWphLCBub3NzbyBtb2RlbG8gZXhwbGljYSA8Yj42My4xNyU8L2I+IGRhIHZhcmnDom5jaWEgZG9zIGRhZG9zLiBWYWxvciByYXpvw6F2ZWwsIGRhZGEgYSBncmFuZGUgZGlzcGVyc8OjbyBwcmVzZW50ZSBub3MgZGFkb3MuCgpUb2RhcyBhcyB2YXJpw6F2ZWlzIGV4cGxpY2F0aXZhcyB1dGlsaXphZGFzIGZvcmFtIHNpZ25pZmljYXRpdmFzIGUsIHBhcmEgb3MgaG9tZW5zLCBhcyBtYWlzIHNpZ25pZmljYXRpdmFzIGZvcmFtIChuZXNzYSBvcmRlbSk6CgoxIC0gQmVsZXphPGJyPgoyIC0gQ29tcGFydGlsaGFtZW50byBkZSBpbnRlcmVzc2VzPGJyPgozIC0gUXXDo28gZW5ncmHDp2FkYSDDqSBhIG91dHJhIHBlc3NvYTxicj4KNCAtIEludGVsaWfDqm5jaWE8YnI+CgpQb3IgZmltLCB2YW1vcyB2aXN1YWxpemFyIG8gbW9kZWxvIG9idGlkby4gQ29tbyB0ZW1vcyA0IHZhcmnDoXZlaXMgZXhwbGljYXRpdmFzIHNlcmlhIG5lY2Vzc8OhcmlvIHVtIGVzcGHDp28gNS1kaW1lbnNpb25hbCBwYXJhIHZpc3VhbGl6YS1sby4gRGV2aWRvIGEgaXNzbyB2YW1vcyB2aXN1YWxpemFyIGRhIHNlZ3VpbnRlIG1hbmVpcmE6CgpFaXhvIHg6IHZhcmnDoXZlbCBhdHRyLjxicj4KRWl4byB5OiBwcmVkacOnw6NvIGZlaXRhIHBlbG8gbW9kZWxvIHBhcmEgYSB2YXJpw6F2ZWwgbGlrZS48YnI+CkNvciBkb3MgcG9udG9zOiB2YXJpw6F2ZWwgZnVuLjxicj4KVGFtYW5obyBkb3MgcG9udG9zOiB2YXJpw6F2ZWwgc2hhci48YnI+CkZhY2V0YXMgZG8gZ3LDoWZpY286IHZhcmnDoXZlbCBpbnRlbC48YnI+CgpgYGB7ciwgZmlnLndpZHRoPTEyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKcGFyYV9wbG90YXJfbW9kZWxvID0gZGFkb3NfaG9tZW5zICU+JSAKICBkYXRhX2dyaWQoYXR0ciA9IHNlcV9yYW5nZShhdHRyLCAxMCksIAogICAgICAgICAgICBmdW4gPSBzZXFfcmFuZ2UoZnVuLCA0KSwgCiAgICAgICAgICAgIGludGVsID0gc2VxX3JhbmdlKGludGVsLCAzKSwKICAgICAgICAgICAgc2hhciA9IHNlcV9yYW5nZShzaGFyLCAzKSkgJT4lIGFkZF9wcmVkaWN0aW9ucyhob21lbnMubW9kZWwpCgpnZ3Bsb3RseShnZ3Bsb3QocGFyYV9wbG90YXJfbW9kZWxvLCBhZXMoeCA9IGF0dHIsIHkgPSBwcmVkKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBmdW4sIHNpemUgPSBzaGFyKSkgKyBmYWNldF9ncmlkKC4gfmludGVsKSkKCmBgYAoKPGgzPkNvbmNsdXNhbzwvaDM+Ck1lIHBhcmVjZSBxdWUgYSBoaXDDs3Rlc2UgcXVlIGZpemVtb3Mgbm8gY29tZcOnbyBkZXNzZSByZWxhdMOzcmlvIGVzdMOhIGNvcnJldGEhIEFwZXNhciBkZSBwYXJhIGFtYm9zIG9zIHNleG9zIG8gZmF0b3IgYmVsZXphIHRlciBzaWRvIG8gbWFpcyBzaWduaWZpY2F0aXZvIG5hIHJlZ3Jlc3PDo28uLi4gQ29udHVkbywgdmltb3MgcXVlIGJlbGV6YSBuw6NvIMOpIG8gw7puaWNvIGZhdG9yIHF1ZSBhcyBwZXNzb2FzIGxldmFtIGVtIGNvbnRhIG5hIGhvcmEgZGUgZ29zdGFyIGFsZ3XDqW0uIAoKUGFyYSBhcyBtdWxoZXJlcyBpbnRlcmVzc2VzIGVtIGNvbXVtIGUgaW50ZWxpZ8OqbmNpYSB0YW1iw6ltIHBhcmVjZW0gc2VyIGZhdG9yZXMgaW1wb3J0YW50ZXMuIErDoSBwYXJhIG9zIGhvbWVucyDDqSBpbXBvcnRhbnRlIHRhbWLDqW0gcXVlIGEgb3V0cmEgcGVzc29hIHNlamEgZW5ncmHDp2FkYSBlIHF1ZSBjb21wYXJ0aWxoZSBpbnRlcmVzc2VzIGVtIGNvbXVtLgoKUG9yw6ltIHZhbGUgbGVtYnJhciBxdWUgZXN0YW1vcyB0cmF0YW5kbyBkZSBzZXJlcyBodW1hbm9zISBFIG51bmNhIHZhbW9zIGNvbnNlZ3VpciBkZWZpbmlyIHVtYSBmw7NybXVsYSBmZWNoYWRhIHBhcmEgYWxnbyB0w6NvIGNvbXBsZXhvIGNvbW8gdW0gcmVsYWNpb25hbWVudG8gZW50cmUgZHVhcyBwZXNzb2FzLi4uIEEgbWluaGEgw6kgZGljYSDDqTogPGI+U2VqYSB2b2PDqiBtZXNtbyEgQXV0ZW50aWNpZGFkZSBuw6NvIGVzdMOhIG5vcyBkYWRvcywgbWFzIGNvbSBjZXJ0ZXphIHNlcmlhIHNpZ25pZmljYXRpdm8gc2UgZXN0aXZlc3NlLjwvYj4=